#pragma once

// Disable warnings about invalid XML
#pragma warning(disable:4635)
#include <Awesomium/WebCore.h>
#pragma warning(default:4635)

using namespace Awesomium;
using namespace System;
using namespace System::Collections::Generic;

namespace AwesomiumDotNet
{
	ref class WebView;

	/// <summary>
	/// An enumeration of the three verbosity settings for the Awesomium Log.
	/// </summary>
	public enum class LogLevel
	{
		/// <summary> No log is created </summary>
		None,
		/// <summary> Logs only errors </summary>
		Normal,
		/// <summary> Logs everything </summary>
		Verbose
	};

	/// <summary>
	/// Configuration settings for the WebCore.
	/// </summary>
	public ref class WebCoreConfig
	{
	private:
		Awesomium::WebCoreConfig* _config;

	internal:
		Awesomium::WebCoreConfig getNative();

	public:
		/// <summary>
		/// Creates a default WebCoreConfig with the following default settings:
		/// <para>EnablePlugins           = false</para>
		/// <para>EnableJavaScript        = true</para>
		/// <para>UserDataPath            = (empty)</para>
		/// <para>PluginPath              = (empty)</para>
		/// <para>LogPath                 = (empty)</para>
		/// <para>LogLevel                = Normal</para>
		/// <para>UserAgentOverride       = (empty)</para>
		/// <para>ProxyServer             = "none"</para>
		/// <para>ProxyConfigScript       = (empty)</para>
		/// <para>SaveCacheAndCookies     = false</para>
		/// <para>MaxCacheSize            = 0</para>
		/// <para>DisableSameOriginPolicy = false</para>
		/// <para>CustomCss               = (empty)</para>
		/// </summary>
		WebCoreConfig();

		/// <summary>
		/// Set whether or not to enable embedded plugins (e.g., Flash).
		/// </summary>
		void SetEnablePlugins(bool enablePlugins);

		/// <summary>
		/// Set whether or not JavaScript is enabled.
		/// </summary>
		void SetEnableJavaScript(bool enableJavaScript);

		/// <summary>
		/// Set the path to the directory that will be used to store cache, 
		/// cookies, and other data. If an empty string is specified, this path 
		/// defaults to "./Default".
		/// </summary>
		void SetUserDataPath(String^ userDataPath);

		/// <summary>
		/// Set an absolute path that will be included in the search for plugins. 
		/// This is useful if you wish to bundle certain plugins with your 
		/// application.
		/// </summary>
		void SetPluginPath(String^ pluginPath);

		/// <summary>
		/// Set the path to store the awesomium.log. If none is specified, the
		/// log will be stored in the working directory.
		/// </summary>
		void SetLogPath(String^ logPath);

		/// <summary>
		/// Set the logging level to use, this can be either None,
		/// Normal, or Verbose.
		/// </summary>
		void SetLogLevel(LogLevel logLevel);

		/// <summary>
		/// Set the user agent string that will be used to override the default. 
		/// Leave this empty to use the default user agent.
		/// </summary>
		void SetUserAgentOverride(String^ userAgentOverride);

		/// <summary>
		/// Set this to configure the proxy settings for all network requests.
		/// Specify "none" to disable all proxy use, specify "auto" to attempt
		/// to detect the proxy using system settings (e.g., via the 
		/// Internet Properties dialog. Specify anything else to set
		/// manual proxy settings.
		/// <para>"none"                         -- No proxy. (Default).</para>
		/// <para>"auto"                         -- Detect system proxy settings.</para>
		/// <para>"http=myproxy:80;ftp=myproxy2" -- Use HTTP proxy "myproxy:80" for http:// URLs, and HTTP proxy "myproxy2:80" for ftp:// URLs.</para>
		/// <para>"myproxy:80"                   -- Use HTTP proxy "foopy:80" for all URLs.</para>
		/// <para>"socks4://myproxy"             -- Use SOCKS v4 proxy "foopy:1080" for all URLs.</para>
		/// </summary>
		void SetProxyServer(String^ proxyServer);

		/// <summary>
		/// Set the URL to the PAC (Proxy Auto-Config) Script to use.
		/// See http://en.wikipedia.org/wiki/Proxy_auto-config for more info.
		/// </summary>
		void SetProxyConfigScript(String^ proxyConfigScript);

		/// <summary>
		/// Set whether or not cache and cookies should be saved to disk.
		/// This is useful for pers
		/// </summary>
		void SetSaveCacheAndCookies(bool saveCacheAndCookies);

		/// <summary>
		/// Set the maximum disk space to be used by the disk cache, in bytes.
		/// Specify 0 to use no limit.
		/// </summary>
		void SetMaxCacheSize(int maxCacheSize);

		/// <summary>
		/// Set whether or not the "same-origin" policy should be disabled.
		/// See http://en.wikipedia.org/wiki/Same_origin_policy
		/// </summary>
		void SetDisableSameOriginPolicy(bool disableSameOriginPolicy);

		/// <summary>
		/// Set a string of custom CSS to be included as the global default
		/// style for all pages. This is especially useful for customizing
		/// scrollbars and other look-and-feel elements.
		/// </summary>
		void SetCustomCss(String^ customCss);

		/// <summary>
		/// Set a custom CSS file to be included as the global default style for 
		/// all pages. This is especially useful for customizing scrollbars and 
		/// other look-and-feel elements.
		/// </summary>
		void SetCustomCssFromFile(String^ customCssFilePath);
	};

	/// <summary>
	/// The WebCore manages the creation of WebViews, the internal worker thread,
	/// and various other global states that are required to embed Chromium.
	/// </summary>
	public ref class WebCore : IDisposable
	{
	private:
		static Awesomium::WebCore* webCore = 0;

	internal:
		static List<WebView^>^ webViewList;

	internal:
		static Awesomium::WebCore* getCore();

	public:
		/// <summary>
		/// Instantiates the WebCore singleton (you can access it later with WebCore.Get).
		/// </summary>
		WebCore();

		/// <summary>
		/// Instantiates the WebCore singleton (you can access it later with WebCore.Get.
		/// </summary>
		/// <param name="config">
		/// Various configuration settings. See WebCoreConfig for more information.
		/// </param>
		WebCore(WebCoreConfig^ config);

		/// <summary>
		/// Destroys the WebCore singleton. (Also destroys any lingering WebViews)
		/// </summary>
		virtual ~WebCore();

	public:
		/// <summary>
		/// Whether or not the WebCore has been Disposed.
		/// </summary>
		property bool IsDisposed
		{
			virtual bool get();
		}

		/// <summary>
		/// The current base directory.
		/// </summary>
		/// <value>
		/// The absolute path to your base directory. 
		/// The base directory is a location that holds
		/// all of your local assets. It will be used 
		/// for WebView.LoadFile and WebView.LoadHtml
		/// (to resolve relative URLs).
		/// </value>
		property String^ BaseDirectory
		{
			String^ get();
			void set(String^ value);
		}

		/// <summary>
		/// Whether or not plugins are enabled.
		/// </summary>
		property bool ArePluginsEnabled
		{
			bool get();
		}

		/// <summary>
		/// Clear the disk cache and media cache.
		/// </summary>
		void ClearCache();

		/// <summary>
		/// Clear all cookies.
		/// </summary>
		void ClearCookies();

		/// <summary>
		/// Creates a new WebView.
		/// </summary>
		/// <param name="width">
		/// The width of the WebView in pixels.
		/// </param>
		/// <param name="height">
		/// The height of the WebView in pixels.
		/// </param>
		/// <returns>
		/// Returns a WebView Instance.
		/// </returns>
		WebView^ CreateWebView(int width, int height);

		/// <summary>
		/// Sets a cookie for a certain URL.
		/// </summary>
		/// <param name="url">
		/// The URL to set the cookie on.
		/// </param>
		/// <param name="cookieString">
		/// The cookie string, for example: "key1=value1; key2=value2"
		/// </param>
		/// <param name="isHttpOnly">
		/// Whether or not this cookie is HTTP-only.
		/// </param>
		/// <param name="forceSessionCookie">
		/// Whether or not to force this as a session cookie.
		/// </param>
		/// <returns>
		/// True if the cookie was successfully set, false otherwise.
		/// </returns>
		bool SetCookie(String^ url, String^ cookieString, bool isHttpOnly, bool forceSessionCookie);

		/// <summary>
		/// Sets a cookie for a certain URL.
		/// </summary>
		/// <param name="url">
		/// The URL to set the cookie on.
		/// </param>
		/// <param name="cookieString">
		/// The cookie string, for example: "key1=value1; key2=value2"
		/// </param>
		/// <param name="isHttpOnly">
		/// Whether or not this cookie is HTTP-only.
		/// </param>
		/// <returns>
		/// True if the cookie was successfully set, false otherwise.
		/// </returns>
		bool SetCookie(String^ url, String^ cookieString, bool isHttpOnly);

		/// <summary>
		/// Sets a cookie for a certain URL.
		/// </summary>
		/// <param name="url">
		/// The URL to set the cookie on.
		/// </param>
		/// <param name="cookieString">
		/// The cookie string, for example: "key1=value1; key2=value2"
		/// </param>
		/// <returns>
		/// True if the cookie was successfully set, false otherwise.
		/// </returns>
		bool SetCookie(String^ url, String^ cookieString);

		/// <summary>
		/// Gets all cookies for a certain URL.
		/// </summary>
		/// <param name="url">
		/// The URL whose cookies will be retrieved.
		/// </param>
		/// <param name="excludeHTTPOnly">
		/// Whether or not to exclude HTTP-only cookies from the result.
		/// </param>
		/// <returns>
		/// Returns the cookie string.
		/// </returns>
		String^ GetCookies(String^ url, bool excludeHTTPOnly);

		/// <summary>
		/// Gets all cookies for a certain URL.
		/// </summary>
		/// <param name="url">
		/// The URL whose cookies will be retrieved.
		/// </param>
		/// <returns>
		/// Returns the cookie string.
		/// </returns>
		String^ GetCookies(String^ url);

		/// <summary>
		/// Deletes a certain cookie on a certain URL.
		/// </summary>
		/// <param name="url">
		/// The URL that we will be deleting cookies on.
		/// </param>
		/// <param name="cookieName">
		/// The name of the cookie that will be deleted.
		/// </param>
		/// <returns>
		/// Returns the cookie string.
		/// </returns>
		void DeleteCookie(String^ url, String^ cookieName);

		/// <summary>
		/// Sets a custom response page to use when a WebView encounters a 
		/// certain HTML status code from the server (like '404 - File not found').
		/// </summary>
		/// <param name="statusCode">
		/// The status code this response page should be associated with.
		/// See http://en.wikipedia.org/wiki/List_of_HTTP_status_codes
		/// </param>
		/// <param name="filePath">
		/// The local page to load as a response, should be a path relative to the base directory.
		/// </param>
		void SetCustomResponsePage(int statusCode, String^ filePath);

		/// <summary>
		/// Updates the WebCore and allows it to conduct various operations such
		/// as updating the render buffer of each WebView, destroying any
		/// WebViews that are queued for destruction, and invoking any queued
		/// WebViewListener events.
		/// </summary>
		void Update();

		/// <summary>
		/// Set whether or not the printer dialog should be suppressed or not.
		/// Set this to "true" to hide printer dialogs and print immediately
		/// using the OS's default printer when WebView.Print is called.
		/// Default is "false" if you never call this.
		/// </summary>
		/// <param name="suppress">
		/// Whether or not the printer dialog should be suppressed.
		/// </param>
		void SetSuppressPrinterDialog(bool suppress);
	};
}
